# OracleAS 10g Portlet Developer Kit (PDK)
Using the Struts Sample

Creation Date: | October 29, 2003
Status: | Production
Version: | PDK Release 2, (9.0.4.0.2 and later)

## Overview

The Apache Struts framework allows developers to write web applications using the Model View Controller (MVC) architecture. As of version 9.0.4.0.2 it is possible to use Struts to write multi-page web provider portlets or to take an existing Struts application and access it as a web provider portlet. This document describes the various files in the sample code. It includes a brief introduction to the MVC pattern and Struts but it is assumed that the reader is already familiar with these topics. If not there are links to the Struts web site which covers both of these topics in detail.

## Background

The Struts framework allows web applications to be developed according to the Model View Controller model where an application is split into three main areas.

- Model components are responsible for defining the business logic and interacting with the application data model. In the case of Struts these are implemented using action classes.
- View components, i.e. the pages via which a user interacts with the application. In the Struts framework these are written as JSPs with Struts specific custom tags.
- Controller components are used to call the correct model components to update application data and then hand off operation to the appropriate view. The Struts controller servlet is defined in a web applications web.xml file and uses a configuration file (struts-config.xml) to define which action handler classes deal with a given request and, depending on the outcome from these action classes, which views should be returned to the user.

More information about Struts can be found at the Struts web site.

The web provider now supports writing portlets using Struts tags. The portlet is written as a Struts servlet and deployed in the same web application. Requests to that portlet are handled by a Struts renderer which forwards the requests to the Struts servlet. Most of the Struts custom tags that are used to write JSPs will work as they stand, but the ones used for navigation, e.g. link and form tags will direct the user outside the Portal environment, so PDK specific versions of these tags are used instead. The tags are based on version 1.1 of the Struts tag library.

## Registering the Struts sample

The Struts sample code is packaged within the sample ear file in its own web application archive file. To run it perform the following steps:

- Deploy the sample ear file (jpdk.ear) in your web container of choice. Once deployed there will be two web applications you can test this by looking at the appropriate test pages. To test that the Struts sample has been successfully deployed try the URL http://<host_name>:<host_port>/jpdk/providers/struts in a browser to see the test page.
- Register the provider from a Portal instance. The relevant settings are:
  - Web provider URL : http://<host_name>:<host_port>/pdkstruts/providers/struts, where host_name and host_port refer to the machine on which the web provider is deployed.
  - Login frequency: Once Per User Session. Struts servlets use session information.

## Struts sample

The Struts sample application that is provided is a simple multi-page application used to add customer names to an internal list and to view that list as shown in the following diagram.

Warning: For the sake of simplicity, the customer list is stored internally using a session attribute. This is not a suitable method to use in a real world application to persist application data. It also means that if the Struts sample provider is registered with a login frequency of Always that the sample will not work since a new session will be established for each portlet request.

### Sample components

Once the sample ear file is deployed, the following files can be seen.

#### Configuration files

The first of these is <web_app_root>/WEB-INF/web.xml. The web provider and Struts servlet are deployed in the same application so the web configuration file (web.xml) contains information about both. The web provider parts of this are the same as for any other web provider but there are additional Struts specific entries (which are labeled). Descriptions of these may be found at the Struts web site. The web configuration file includes a list of tag library definitions which consists of the normal Struts tags and a web provider specific version, e.g. the following definition for the Struts html tag library defines its URI and the location of the tag library definition file which describes the tags in that library and their implementation classes.

    <taglib>
        <taglib-uri>/WEB-INF/tlds/struts-html.tld</taglib-uri>
        <taglib-location>/WEB-INF/tlds/struts-html.tld</taglib-location>
    </taglib>

Any jsp file using a custom tag must include a reference to the tag library uri which contains the tag. For example, a JSP written as part of a stand-alone Struts application that used the link tag would include something like:

    <%@ taglib uri="/WEB-INF/tlds/struts-html.tld" prefix="html" %>
      .
      .
    <html:link page="/actionName.do">Link text</html:link>

Now, if that Struts application were deployed behind a web provider without any changes, the rendered link would take the user directly to the stand-alone Struts application. To make this work as part of a portlet, you could change the taglib directive at the start of each jsp to refer to the PDK version of this tag library. However, the simplest way to do this would be to change the tag library location in web.xml, so

    <taglib>
        <taglib-uri>/WEB-INF/tlds/struts-html.tld</taglib-uri>
        <taglib-location>/WEB-INF/tlds/struts-html.tld</taglib-location>
    </taglib>

becomes

    <taglib>
        <taglib-uri>/WEB-INF/tlds/struts-html.tld</taglib-uri>
        <taglib-location>/WEB-INF/tlds/pdk-struts-html.tld</taglib-location>
    </taglib>

The web configuration file also contains a reference to the Struts configuration file, <web_app_root>/WEB-INF/struts-config.xml. This file is used by Struts to wire together the various JSPs in the Struts application.

#### Struts libraries

The Struts libraries (version 1.1) are included in the directory <web_app_root>/WEB-INF/lib. Any provider hosting a portlet which uses Struts tags or the web provider versions must include these libraries.

#### Struts tag library definitions

The Struts tag library definition files define each of the tags used when writing jsp files and are located in <web_app_root>/WEB-INF/tlds. Any provider hosting a portlet which uses Struts tags must include these definitions.

#### PDK Sample library

The jar file containing the java action classes for the sample is contained in the file, <web_app_root>/WEB-INF/lib/pdkstruts.jar. This file is used for the sample only.

#### PDK Struts tag libraries

The jar file containing the code for the PDK versions (pdkstruts.jar) of the Struts html tags is located in <web_app_root>/WEB-INF/lib. Any provider hosting a portlet which uses the PDK Struts tags must include this library.

The PDK specific tags included in this library are:

- link - used to generate a hyperlink in a page.
- form - used to generate form mark-up
- img - used to generate image mark-up. The sample uses the PDK version of the tag so that images stored on the web provider server may be used in the portlet. In general, however, images that are used in portlets should be stored on the Portal middle tier since web providers deployed on a separate machine to the Portal middle tier are not exposed through firewalls. In this case, the Struts version of this tag could be used.
- rewrite - like link, but just renders the url

#### PDK Struts tag definition file

The tag definition file for the PDK Struts tags (pdk-struts-html.tld) is located in <web_app_root>/WEB-INF/tlds. Any provider hosting a portlet which uses the PDK version of the Struts tags must include this library.

#### Provider definition file

The provider definition file (provider.xml) is located in <web_app_root>/WEB-INF/providers/struts.

       <?xml version = '1.0' encoding = 'UTF-8'?>
       <?providerDefinition version="3.1"?>
       <provider class="oracle.portal.provider.v2.DefaultProviderDefinition">
           <session>true</session>
           <passAllUrlParams>true</passAllUrlParams>
           <portlet class="oracle.portal.provider.v2.DefaultPortletDefinition">
               <id>1</id>
               <name>StrutsPortlet</name>
               <title>Struts demo Portlet</title>
               <description>Demonstrates a Struts demo app running behind a portlet.</description>
               <timeout>40</timeout>
               <showEditToPublic>false</showEditToPublic>
               <hasAbout>false</hasAbout>
               <showEdit>false</showEdit>
               <hasHelp>false</hasHelp>
               <showEditDefault>false</showEditDefault>
               <showDetails>false</showDetails>
               <renderer class="oracle.portal.provider.v2.render.RenderManager">
                   <renderContainer>true</renderContainer>
                   <renderCustomize>true</renderCustomize>
                   <autoRedirect>true</autoRedirect>
                   <contentType>text/html</contentType>
                   <showPage class="oracle.portal.provider.v2.render.http.StrutsRenderer">
                       <defaultAction>/htdocs/struts/mainPage.jsp</defaultAction>
                   </showPage>
               </renderer>
           </portlet>
       </provider>

The important points to note are that the provider uses sessions, has passAllUrlParams set to true and that the portlet uses the StrutsRenderer class. The renderer also has a defaultAction property that defines the page which will be rendered the first time the portlet is called. The reason for the first two points is covered in the next section.

## Restrictions

There are a few restrictions that should be noted when writing portlets that use the Struts framework or configuring a provider portlet to use an existing Struts application.

- The Struts servlet must be in the same servlet context as the web provider. This is because the Struts servlet will use the same session as the web provider itself.
- Redirection may not be used (unless the aim is to take the user out of the Portal context to another application). One scenario where redirects are used is to prevent a page reload causing form values to be resubmitted to an application. The recommended way around this in a portlet environment is to use a synchronizer token. This is demonstrated in the sample where the UpdateCustomerStoreAction action handler detects duplicate submissions and sets a parameter in the forward to the customerAdded.jsp page. The sample code actually flags a warning to demonstrate the idea, a real-world application would probably deal with this in a more elegant manner.

####

Revision History: |
Revision No | Last Update
1.0 | October 29, 2003

Oracle Corporation World Headquarters 500 Oracle Parkway Redwood Shores, CA 94065, USA http://www.oracle.com/ | Worldwide Inquiries: 1-800-ORACLE1 Fax 650.506.7200 | Copyright and Corporate Info